package com.spring.demo3.eg3;

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Dispatcher;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

/**
 * 通过cglib创建一个代理类，父类为UserService，并且实现IMethodInfo接口，将接口IMethodInfo所有
 * 方法的转发给DefaultMethodInfo处理，代理类中的其他方法，转发给其父类UserService处理
 *
 * @author vhans
 */
public class Test {
    @org.junit.Test
    public void test() {
        Class<?> targetClass = UserService.class;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setInterfaces(new Class[]{IMethodInfo.class});

        // 创建一个方法统计器
        DefaultMethodInfo defaultMethodInfo = new DefaultMethodInfo(targetClass);

        // 创建回调器列表，一个用来处理UserService中的所有方法，另一个用来处理IMethodInfo中的方法
        Callback[] callbacks = {
                (MethodInterceptor) (o, method, objects, methodProxy) -> methodProxy.invokeSuper(o, objects),
                (Dispatcher) () -> {
                    /*
                      用来处理代理对象中IMethodInfo接口中的所有方法
                      所以此处返回的为IMethodInfo类型的对象，
                      将由这个对象来处理代理对象中IMethodInfo接口中的所有方法
                     */
                    return defaultMethodInfo;
                }
        };

        // 绑定回调器
        enhancer.setCallbacks(callbacks);
        enhancer.setCallbackFilter(method -> {
            // 当方法在IMethodInfo中定义的时候，返回callbacks中的第二个元素
            return method.getDeclaringClass() == IMethodInfo.class ? 1 : 0;
        });

        Object proxy = enhancer.create();

        UserService us = (UserService) proxy;
        us.add();
        us.update();

        IMethodInfo im = (IMethodInfo) proxy;
        System.out.println(im.methodCount());
        System.out.println(im.methodNames());
    }
}
